package com.motorhome.h5.service.impl;

import com.motorhome.base.cache.MemcachedCache;
import com.motorhome.base.session.CookieSession;
import com.motorhome.base.sms.AliyunSms;
import com.motorhome.base.util.*;
import com.motorhome.h5.common.statics.H5Statics;
import com.motorhome.h5.dao.LoginDao;
import com.motorhome.h5.dao.VipDao;
import com.motorhome.h5.domain.OpenGetMemberResult;
import com.motorhome.h5.domain.OpenMember;
import com.motorhome.h5.domain.User;
import com.motorhome.h5.domain.Vip;
import com.motorhome.h5.service.CommonService;
import com.motorhome.h5.service.LoginService;
import com.motorhome.h5.service.OpenService;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;


/**
 * @author: John
 */
@Service
public class LoginServiceImpl implements LoginService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private LoginDao loginDao;

    @Autowired
    private CommonService commonService;

    @Autowired
    private MemcachedCache cache;

    @Autowired
    private OpenService openService;

    @Autowired
    private VipDao vipDao;

    @Override
    public Result doLogin(HttpServletRequest request, HttpServletResponse response, String phone, String code, String openId) {

        if (StringUtil.isBlank(phone)) {
            return new Result(1, "手机号码必填");
        }

        if (StringUtil.isBlank(code)) {
            return new Result(1, "验证码必填");
        }

        final String codeKey = "H5_LOGIN_CODE_" + phone;
        String cacheCode = (String)cache.get(codeKey);
        if (cacheCode == null || !cacheCode.equals(code)) {
            return new Result(2, "验证码不正确");
        }
        cache.delete(codeKey);

        User user = commonService.getUserByPhone(phone);

        //本平台用户不存在
        if (user == null) {

            //1、查询开放平台是否存在
            String memberInfo = openService.getMemberInfo(phone);
            if (memberInfo != null) {
                OpenGetMemberResult openGetMemberResult = JsonUtil.fromJson(memberInfo, OpenGetMemberResult.class);
                if (openGetMemberResult != null && openGetMemberResult.getStatus() == 0) {
                    List<OpenMember> openMembers = openGetMemberResult.getData();
                    if (openMembers != null && !openMembers.isEmpty()) {
                        OpenMember openMember = openMembers.get(0);
                        loginDao.insertOpenUser(phone, openMember.getTrueName(), openMember.getCardId(), openId);
                        user = commonService.getUserByPhone(phone);
                    }
                }
            }

            //2、开放平台不存在，自动注册用户并同步至开放平台
            if (user == null) {
                loginDao.insertUser(phone, openId);
                user = commonService.getUserByPhone(phone);
                openService.addMember(user.getPhone(), "888888", user.getUserName(), user.getPhone(), openId);
            }
        }

        //微信端登录，更新用户OpenId
        if (user != null && !StringUtil.isBlank(openId)) {
            loginDao.updateUserOpenId(user.getId(), openId);
        }

        //开放平台查询并设置用户会员信息
        setUserVipInfo(user);

        cache.set("H5_USER_" + user.getId(), user, "24h");

        //写入Session
        CookieSession session = new CookieSession(request, response, H5Statics.SESSION_KEY);
        session.put("uid", "" + user.getId());
        session.flush(response);
        return new Result(0, "登录成功", request.getParameter("source"));
    }

    public void setUserVipInfo(User user) {
        String memberInfo = openService.getMemberInfo(user.getPhone());
        if (memberInfo != null) {
            OpenGetMemberResult openGetMemberResult = JsonUtil.fromJson(memberInfo, OpenGetMemberResult.class);
            if (openGetMemberResult != null && openGetMemberResult.getStatus() == 0) {
                List<OpenMember> openMembers = openGetMemberResult.getData();
                if (openMembers != null && !openMembers.isEmpty()) {
                    OpenMember openMember = openMembers.get(0);
                    List<Vip> vips = vipDao.getVipList();
                    for (Vip vip : vips) {
                        if (vip.getName().equals(openMember.getMemberGroupName())) {
                            user.setVipId(vip.getId());
                            user.setVipName(vip.getName());
                            user.setVipRate(vip.getRate());
                            break;
                        }
                    }
                }
            }
        }
    }

    @Override
    public Result doReg(User loginUser, String password, String realName) {
        String md5Pass = DigestUtils.md5Hex(password);
        loginDao.updateUser(loginUser.getId(), md5Pass, realName);
        User user = commonService.getUserById(loginUser.getId());
        cache.set("H5_USER_" + user.getId(), user, "24h");

        //同步用户数据至开放平台
        openService.addMember(user.getPhone(), password, user.getUserName(), user.getPhone(), null);

        return new Result(0, "注册成功");
    }

    @Override
    public Result sendCode(String phone) {

        final String codeKey = "H5_LOGIN_CODE_" + phone;
        String code = (String)cache.get(codeKey);
        if (StringUtil.isBlank(code)) {
            code = RandomUtil.random(6);
        }
        cache.set(codeKey, code, "5min");

        logger.info("code=" + cache.get(codeKey));

        try {
            boolean result = new AliyunSms(
                    H5Statics.ALIYUN_SMS_ACCESSKEYID,
                    H5Statics.ALIYUN_SMS_ACCESSKEYSECRET,
                    H5Statics.ALIYUN_SMS_SIGNNAME,
                    H5Statics.ALIYUN_SMS_TEMPLATECODE
            ).sendCode(phone, code, "5");
            if (result) {
                return new Result(0, "发送成功");
            }
        } catch (Exception e) {
            logger.error("短信发送异常", e);
        }
        return new Result(1, "发送失败");
    }

}
